package com.qiangesoft.blog.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qiangesoft.blog.common.constants.FieldConstants;
import com.qiangesoft.blog.system.entity.SysMenu;
import com.qiangesoft.blog.system.entity.SysRoleMenu;
import com.qiangesoft.blog.system.exception.BusinessException;
import com.qiangesoft.blog.system.mapper.SysMenuMapper;
import com.qiangesoft.blog.system.service.ISysMenuService;
import com.qiangesoft.blog.system.service.ISysRoleMenuService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 * 资源权限 服务实现类
 * </p>
 *
 * @author qiange
 * @since 2023-06-01
 */
@Service
@RequiredArgsConstructor
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements ISysMenuService {

    private final ISysRoleMenuService roleMenuService;

    @Override
    public List<SysMenu> listMenuByRoleIds(List<Long> roleIds) {
        LambdaQueryWrapper<SysRoleMenu> roleMenuWrapper = new LambdaQueryWrapper<>();
        roleMenuWrapper.in(SysRoleMenu::getRoleId, roleIds);
        List<SysRoleMenu> roleMenuList = roleMenuService.list(roleMenuWrapper);
        if (CollectionUtils.isEmpty(roleMenuList)) {
            return Collections.emptyList();
        }
        Set<Long> menuIds = roleMenuList.stream().map(SysRoleMenu::getMenuId).collect(Collectors.toSet());
        return baseMapper.selectBatchIds(menuIds);
    }

    @Override
    public List<SysMenu> listMenuByRoleId(Long roleId) {
        LambdaQueryWrapper<SysRoleMenu> roleMenuWrapper = new LambdaQueryWrapper<>();
        roleMenuWrapper.eq(SysRoleMenu::getRoleId, roleId);
        List<SysRoleMenu> roleMenuList = roleMenuService.list(roleMenuWrapper);
        if (CollectionUtils.isEmpty(roleMenuList)) {
            return Collections.emptyList();
        }
        Set<Long> menuIds = roleMenuList.stream().map(SysRoleMenu::getMenuId).collect(Collectors.toSet());
        return baseMapper.selectBatchIds(menuIds);
    }

    @Override
    public List<SysMenu> listMenuTree(List<SysMenu> list) {
        List<SysMenu> resultList = new ArrayList<>();
        for (SysMenu menu : list) {
            Long parentId = menu.getParentId();
            if (parentId == null || parentId == 0)
                resultList.add(menu);
        }
        for (SysMenu menu : resultList) {
            menu.setChildren(getChild(menu.getId(), list));
        }
        return resultList;
    }

    @Override
    public List<SysMenu> listMenuApi(Long id) {
        QueryWrapper<SysMenu> queryWrapper = new QueryWrapper<SysMenu>()
                .eq("level", 1).eq(id != null, FieldConstants.ID, id);
        List<SysMenu> list = baseMapper.selectList(queryWrapper);
        for (SysMenu menu : list) {
            List<SysMenu> childrens = baseMapper.selectList(new QueryWrapper<SysMenu>().eq(FieldConstants.PARENT_ID, menu.getId()));
            menu.setChildren(childrens);
        }
        return list;
    }

    @Override
    public void insertMenu(SysMenu menu) {
        int rows = baseMapper.insert(menu);
        if (rows == 0) {
            throw new BusinessException("添加菜单失败");
        }
    }

    @Override
    public void updateMenu(SysMenu menu) {
        int rows = baseMapper.updateById(menu);
        if (rows == 0) {
            throw new BusinessException("修改菜单失败");
        }
    }

    @Override
    public void deleteMenuById(Long id) {
        int rows = baseMapper.deleteById(id);
        if (rows == 0) {
            throw new BusinessException("删除菜单失败");
        }
    }


    /**
     * 构造树
     *
     * @param pid
     * @param menus
     * @return
     */
    private List<SysMenu> getChild(Long pid, List<SysMenu> menus) {
        List<SysMenu> childrens = new ArrayList<>();
        for (SysMenu e : menus) {
            Long parentId = e.getParentId();
            if (parentId != null && parentId.equals(pid)) {
                // 子菜单的下级菜单
                childrens.add(e);
            }
        }
        // 把子菜单的子菜单再循环一遍
        for (SysMenu e : childrens) {
            // childrens
            e.setChildren(getChild(e.getId(), menus));
        }
        //停下来的条件，如果 没有子元素了，则停下来
        if (childrens.size() == 0) {
            return null;
        }
        return childrens;
    }
}
